"""
ConnLLM命令行接口
提供命令行工具来访问ConnLLM功能
"""
import argparse
import sys
import json
import logging
from typing import List, Dict, Any, Optional

from .core.pricing import PricingManager, get_pricing_manager
from .core.keys import KeyManager
from . import (
    complete, complete_stream, create_provider,
    ConfigManager, KeyManager, PricingManager
)

# 设置日志
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
)
logger = logging.getLogger("connllm.cli")


def main():
    """命令行入口点"""
    parser = argparse.ArgumentParser(description="ConnLLM命令行工具")
    
    # 配置选项
    parser.add_argument("--provider", type=str, help="提供商类型，如'anthropic'、'openai'等")
    parser.add_argument("--model", type=str, help="模型名称，如'claude-3-5-sonnet'、'gpt-4o'等")
    parser.add_argument("--config", type=str, help="使用的配置名称")
    parser.add_argument("--temperature", type=float, help="生成多样性参数(0-1)")
    parser.add_argument("--max-tokens", type=int, help="最大生成token数")
    parser.add_argument("--stream", action="store_true", help="使用流式响应")
    parser.add_argument("--proxy", type=str, help="代理地址，如'http://127.0.0.1:7890'")
    
    # API密钥管理
    parser.add_argument("--set-key", type=str, help="设置的提供商名称")
    parser.add_argument("--key-value", type=str, help="API密钥值")
    parser.add_argument("--list-keys", action="store_true", help="列出所有已配置的API密钥")
    
    # 配置管理
    parser.add_argument("--list-configs", action="store_true", help="列出所有预定义配置")
    parser.add_argument("--save-config", type=str, help="保存当前配置的名称")
    
    # 价格管理
    parser.add_argument("--list-prices", action="store_true", help="列出所有价格信息")
    parser.add_argument("--set-price", type=str, help="设置价格的模型，格式为'provider/model'")
    parser.add_argument("--input-price", type=float, help="输入价格(美元/1000tokens)")
    parser.add_argument("--output-price", type=float, help="输出价格(美元/1000tokens)")
    
    # 日志级别
    parser.add_argument("--verbose", action="store_true", help="启用详细日志")
    parser.add_argument("--debug", action="store_true", help="启用调试日志")
    
    # 特定提供商选项
    parser.add_argument("--search", action="store_true", help="启用搜索功能(仅Moonshot支持)")
    
    # 提示输入
    parser.add_argument("prompt", nargs="*", help="提示文本")
    
    args = parser.parse_args()
    
    # 设置日志级别
    if args.debug:
        logging.getLogger("connllm").setLevel(logging.DEBUG)
    elif args.verbose:
        logging.getLogger("connllm").setLevel(logging.INFO)
    
    # 处理API密钥管理
    if args.list_keys:
        _list_keys()
        return
        
    if args.set_key:
        if not args.key_value:
            parser.error("设置API密钥需要同时指定--key-value")
        _set_key(args.set_key, args.key_value)
        return
    
    # 处理配置管理
    if args.list_configs:
        _list_configs()
        return
        
    # 处理价格管理
    if args.list_prices:
        _list_prices()
        return
        
    if args.set_price:
        if args.input_price is None or args.output_price is None:
            parser.error("设置价格需要同时指定--input-price和--output-price")
        _set_price(args.set_price, args.input_price, args.output_price)
        return
    
    # 构建配置
    overrides = {}
    if args.provider:
        overrides["provider"] = args.provider
    if args.model:
        overrides["model"] = args.model
    if args.temperature is not None:
        overrides["temperature"] = args.temperature
    if args.max_tokens is not None:
        overrides["max_tokens"] = args.max_tokens
    if args.proxy:
        overrides["proxy"] = args.proxy
    if args.search:
        overrides["search"] = True
    
    # 如果是交互模式，没有提供提示文本
    if not args.prompt and sys.stdin.isatty():
        # 交互模式
        _run_interactive_mode(args.config, overrides, args.stream)
    else:
        # 批处理模式
        prompt = " ".join(args.prompt) if args.prompt else sys.stdin.read().strip()
        _process_prompt(prompt, args.config, overrides, args.stream)


def _list_keys():
    """列出所有已配置的API密钥"""
    key_manager = KeyManager()
    keys = key_manager.list_keys()
    
    print("API密钥配置:")
    for provider, key in keys.items():
        if key:
            # 显示部分密钥，保护隐私
            masked_key = key[:5] + "*" * (len(key) - 10) + key[-5:] if len(key) > 15 else "*" * len(key)
            status = "\033[92m可用\033[0m"  # 绿色
        else:
            masked_key = "未设置"
            status = "\033[93m未配置\033[0m"  # 黄色
            
        print(f"  {provider:<12}: {masked_key} ({status})")


def _set_key(provider: str, api_key: str):
    """设置API密钥"""
    key_manager = KeyManager()
    key_manager.set_key(provider, api_key)
    print(f"已设置{provider}的API密钥")


def _list_configs():
    """列出所有预定义配置"""
    config_manager = ConfigManager()
    configs = config_manager.configs
    
    print("预定义配置:")
    for name, config in configs.items():
        provider = config.get("provider", "unknown")
        model = config.get("model", "unknown")
        temperature = config.get("temperature", 0.0)
        max_tokens = config.get("max_tokens", 0)
        
        print(f"  {name:<16}: {provider}/{model} (温度={temperature}, 最大token={max_tokens})")


def _list_prices():
    """列出所有价格信息"""
    pricing_manager = get_pricing_manager()
    
    print("价格信息 (美元/1000tokens):")
    for provider in pricing_manager.list_providers():
        print(f"* {provider}:")
        provider_pricing = pricing_manager.get_provider_pricing(provider)
        
        if not provider_pricing:
            print("  无价格信息")
            continue
            
        for model, prices in provider_pricing.items():
            input_price = prices.get("input", 0.0)
            output_price = prices.get("output", 0.0)
            print(f"  {model:<24}: 输入=${input_price:.6f}, 输出=${output_price:.6f}")


def _set_price(model_path: str, input_price: float, output_price: float):
    """设置模型价格"""
    if "/" not in model_path:
        print("错误: 模型路径格式应为'provider/model'，如'anthropic/claude-3-5-sonnet'")
        return
        
    provider, model = model_path.split("/", 1)
    pricing_manager = get_pricing_manager()
    pricing_manager.set_price(provider, model, input_price, output_price)
    print(f"已设置{provider}/{model}的价格: 输入=${input_price:.6f}, 输出=${output_price:.6f}")


def _process_prompt(prompt: str, config_name: Optional[str], overrides: Dict[str, Any], stream: bool):
    """处理提示文本"""
    messages = [{"role": "user", "content": prompt}]
    
    try:
        if stream:
            for chunk in complete_stream(messages, config_name, overrides):
                print(chunk, end="", flush=True)
            print()
        else:
            response = complete(messages, config_name, overrides)
            print(response)
    except Exception as e:
        print(f"错误: {e}", file=sys.stderr)
        sys.exit(1)


def _run_interactive_mode(config_name: Optional[str], overrides: Dict[str, Any], stream: bool):
    """运行交互模式"""
    print("ConnLLM 交互模式")
    print("输入'exit'或'quit'退出，输入'clear'清除对话历史")
    
    # 创建提供商
    provider = create_provider(config_name or "default", overrides)
    provider_name = provider.provider_type
    model_name = provider.model
    
    print(f"使用 {provider_name}/{model_name}")
    
    messages: List[Dict[str, str]] = []
    
    while True:
        try:
            user_input = input("\n> ")
            
            if user_input.lower() in ["exit", "quit"]:
                break
                
            if user_input.lower() == "clear":
                messages = []
                print("对话历史已清除")
                continue
                
            # 添加用户消息
            messages.append({"role": "user", "content": user_input})
            
            # 获取响应
            if stream:
                print("\n", end="")
                assistant_message = ""
                for chunk in provider.complete_stream(messages):
                    print(chunk, end="", flush=True)
                    assistant_message += chunk
                print("\n")
            else:
                assistant_message = provider.complete(messages)
                print(f"\n{assistant_message}\n")
                
            # 添加助手消息
            messages.append({"role": "assistant", "content": assistant_message})
            
        except KeyboardInterrupt:
            print("\n已中断")
            break
        except Exception as e:
            print(f"\n错误: {e}")


if __name__ == "__main__":
    main()
